package com.liziguo.lzgfp.client;

import com.liziguo.lzgfp.system.codec.AESCodec;
import com.liziguo.lzgfp.system.codec.JSONObjectCodec;
import com.liziguo.lzgfp.system.util.AESUtil;
import com.liziguo.lzgfp.system.util.RSAUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author: Liziguo
 * @Date: 2021/12/27 14:53
 */
public class SecurityHandler extends SimpleChannelInboundHandler<String> {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private RSAUtil.RSAKey rsaKey;

    //第几次读到数据
    private int index;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
        switch (index++) {
            case 0 -> {
                logger.debug("服务器公钥:{}", s);
                rsaKey = RSAUtil.genKey();
                logger.debug("客户端生成RSA密钥:{}", rsaKey);
                ctx.channel().writeAndFlush(RSAUtil.encrypt(rsaKey.publickey(), s));
            }
            case 1 -> {
                String aesKey = RSAUtil.decrypt(s, rsaKey.privatekey());
                logger.debug("获得AES密钥:{}", aesKey);
                String msg = AESUtil.encryptToString("hello", aesKey);
                ctx.channel().writeAndFlush(msg);
                ctx.pipeline().remove(this);
                ctx.pipeline().remove(StringEncoder.class);
                ctx.pipeline().remove(StringDecoder.class);
                //添加心跳监听
                ctx.pipeline().addFirst(new IdleStateHandler(120, 60, 0));
                //添加AES编解码器
                Globale.aesKey = aesKey;
                ctx.pipeline().addLast(new AESCodec(aesKey));
                ctx.pipeline().addLast(new StringEncoder());
                ctx.pipeline().addLast(new StringDecoder());
                //添加JSON编解码器
                ctx.pipeline().addLast(new JSONObjectCodec());
                //添加业务Handler
                ctx.pipeline().addLast(new ClientHandler());
            }
            default -> ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error(cause.getMessage());
        cause.printStackTrace();
        ctx.close();
    }
}
